/*
 * Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved.
 * Description: 与AI设备(D芯片)相关dnn,runtime,drv等接口适配
 * Author: ligang
 * Create: 2022-02-24
 */

#include <thread>
#include <adapter_hal.h>
#include "dlhal_function.h"
#include "log.h"
#include "sal_pub.h"
#include "runtime/config.h"

using namespace hccl;

int (*g_grpIdCallback)(int tag, int *grpId, int *devId) = nullptr;

#ifdef __cplusplus
extern "C" {
#endif

constexpr u32 MEMORY_PAGE_SIZE = 4096;
constexpr u32 PRE_FETCH_THREADS_NUM = 24;
constexpr u32 PRE_FETCH_MEMORY_THRESHOLD = 268435456; // 考虑到多线程预访问也有开销，只有在内存大于256MB时才启动预访问

HcclResult HcclSetGrpIdCallback(int (*grpIdCallback)(int tag, int *grpId, int *devId))
{
    if (grpIdCallback == nullptr) {
        HCCL_ERROR("para grpIdCallback is nullptr");
        return HCCL_E_PARA;
    }

    g_grpIdCallback = grpIdCallback;
    HCCL_DEBUG("New grpIdCallback was set, grpIdCallback[%p]", grpIdCallback);
    return HCCL_SUCCESS;
}

#ifdef __cplusplus
}
#endif

s32 hrtGetgrpId(int &groupId, int &devId)
{
    if (g_grpIdCallback == nullptr) {
        groupId = HCCL_ESCHED_GROUP_ID;
        devId = HCCL_RESERVED_DEV_ID;

        HCCL_DEBUG("g_grpIdCallback is nullptr, event.grp_id[%d] = HCCL_ESCHED_GROUP_ID", groupId);
    } else {
        HCCL_DEBUG("g_grpIdCallback is not nullptr");
        s32 ret = g_grpIdCallback(0, &groupId, &devId);
        if (ret != 0) {
            HCCL_ERROR("g_grpIdCallback failed, ret[%d]", ret);
            return ret;
        }

        HCCL_DEBUG("g_grpIdCallback is not nullptr, g_grpIdCallback(0) event.grp_id[%d],  devId[%d]", groupId, devId);
    }

    return 0;
}

HcclResult hrtHalSubmitEvent(u32 devId, u32 eventId, u32 groupId)
{
    struct event_summary event = {0};
    event.pid = SalGetPid();
    event.grp_id = groupId;
    event.event_id = static_cast<EVENT_ID>(eventId);
    event.subevent_id = 0;
    event.msg_len = 0;
    event.msg = nullptr;
    event.dst_engine = ACPU_DEVICE;
    event.policy = ONLY;
    for (u32 i = 0; i < EVENT_SUMMARY_RSV; i++) {
        event.rsv[i] = 0;
    }

    HCCL_DEBUG("SubmitEvent: event id:%u, pid:%d, grp id:%u, dev id:%u", eventId, event.pid, event.grp_id, devId);

    drvError_t ret = DlHalFunction::GetInstance().dlHalEschedSubmitEvent(devId, &event);
    CHK_PRT_RET(ret != DRV_ERROR_NONE, HCCL_ERROR("[Submit][Event]errNo[0x%016llx] halEschedSubmitEvent fail,"
        "return[%d], para: deviceLogicId[%u] group[%u] eventId[%u].", HCCL_ERROR_CODE(HCCL_E_DRV),
        ret, devId, event.grp_id, eventId), HCCL_E_DRV);
    return HCCL_SUCCESS;
}

HcclResult hrtHalEschedAttachDevice(unsigned int devId)
{
    drvError_t ret = DlHalFunction::GetInstance().dlHalEschedAttachDevice(devId);
    CHK_PRT_RET(ret != DRV_ERROR_NONE, HCCL_ERROR("[Attach][Device]errNo[0x%016llx] hrtHalEschedAttachDevice fail,"
        "return[%d], para: deviceLogicId[%u].", HCCL_ERROR_CODE(HCCL_E_DRV), ret, devId), HCCL_E_DRV);
    return HCCL_SUCCESS;
}

HcclResult hrtHalEschedDettachDevice(unsigned int devId)
{
    drvError_t ret = DlHalFunction::GetInstance().dlHalEschedDettachDevice(devId);
    CHK_PRT_RET(ret != DRV_ERROR_NONE, HCCL_ERROR("[Dettach][Device]errNo[0x%016llx] hrtHalEschedDettachDevice fail,"
        "return[%d], para: deviceLogicId[%u].", HCCL_ERROR_CODE(HCCL_E_DRV), ret, devId), HCCL_E_DRV);
    return HCCL_SUCCESS;
}

HcclResult hrtHalGetAPIVersion(int &apiVersion)
{
    drvError_t ret = DlHalFunction::GetInstance().dlHalGetAPIVersion(&apiVersion);
    CHK_PRT_RET(ret != DRV_ERROR_NONE, HCCL_ERROR("[Get][APIVersion]errNo[0x%016llx] dlHalGetAPIVersion fail,"
        "return[%d], para: apiVersion[%d].", HCCL_ERROR_CODE(HCCL_E_DRV), ret, apiVersion), HCCL_E_DRV);
    return HCCL_SUCCESS;
}

HcclResult hrtHalEschedCreateGrp(unsigned int devId, unsigned int grpId, GROUP_TYPE type)
{
    drvError_t ret = DlHalFunction::GetInstance().dlHalEschedCreateGrp(devId, grpId, type);
    CHK_PRT_RET(ret == DRV_ERROR_GROUP_EXIST, HCCL_INFO("hal event group is exist, devId[%u] grpId[%u] group type[%u]",
        devId, grpId, type), HCCL_SUCCESS);
    CHK_PRT_RET(ret != DRV_ERROR_NONE, HCCL_ERROR("[hrtHalEschedCreateGrp]errNo[0x%016llx] hrtHalEschedCreateGrp fail,"
        "return[%d], para: devId[%u].", HCCL_ERROR_CODE(HCCL_E_DRV), ret, devId), HCCL_E_DRV);
    return HCCL_SUCCESS;
}

HcclResult hrtHalEschedCreateGrpEx(unsigned int devId, unsigned int *grpId, unsigned int threadNum, GROUP_TYPE type)
{
    struct esched_grp_para grpPara;
    grpPara.type = type;
    grpPara.threadNum = threadNum;
    char groupName[HCCL_DRIVER_GROUP_NAME] = {"hcclGrpName"};
    s32 memRet = memcpy_s(grpPara.grp_name, sizeof(groupName), groupName, sizeof(groupName));
    CHK_PRT_RET(memRet != HCCL_SUCCESS, HCCL_ERROR("[halEschedCreateGrpEx] memcpy fail,"
        "return[%d], para: devId[%u].", memRet, devId), HCCL_E_MEMORY);
    HCCL_INFO("[dlHalEschedCreateGrpEx] get grpPara.grp_name[%s]", grpPara.grp_name);

    memRet = memset_s(grpPara.rsv, sizeof(grpPara.rsv), 0, sizeof(grpPara.rsv));
    CHK_PRT_RET(memRet != HCCL_SUCCESS, HCCL_ERROR("[halEschedCreateGrpEx] memset_s fail,"
        "return[%d], para: devId[%u].", memRet, devId), HCCL_E_MEMORY);

    drvError_t ret = DlHalFunction::GetInstance().dlHalEschedCreateGrpEx(devId, &grpPara, grpId);

    CHK_PRT_RET(ret != DRV_ERROR_NONE, HCCL_ERROR("[halEschedCreateGrpEx]errNo[0x%016llx] createGrpEx fail,"
        "return[%d], para: devId[%u].", HCCL_ERROR_CODE(HCCL_E_DRV), ret, devId), HCCL_E_DRV);
    HCCL_INFO("[dlHalEschedCreateGrpEx] get ret[%d], grpId[%u]", ret, *grpId);
    return HCCL_SUCCESS;
}

HcclResult hrtHalEschedSubscribeEvent(unsigned int devId, unsigned int grpId, unsigned int threadId,
    unsigned long long eventBitmap)
{
    drvError_t ret = DlHalFunction::GetInstance().dlHalEschedSubscribeEvent(devId, grpId, threadId, eventBitmap);
    CHK_PRT_RET(ret != DRV_ERROR_NONE, HCCL_ERROR("[Subscribe][Event]errNo[0x%016llx] hrtHalEschedSubscribeEvent fail,"
        "return[%d], para: devId[%u].", HCCL_ERROR_CODE(HCCL_E_DRV), ret, devId), HCCL_E_DRV);
    HCCL_DEBUG("[hrtHalEschedSubscribeEvent] devId[%u] grpId[%u] threadId[%u] eventBitmap[%llu]",
        devId, grpId, threadId, eventBitmap);
    return HCCL_SUCCESS;
}

HcclResult hrtHalEschedWaitEvent(unsigned int devId, unsigned int grpId, unsigned int threadId, int timeout,
    struct event_info *event)
{
    CHK_PTR_NULL(event);
    drvError_t ret = DlHalFunction::GetInstance().dlHalEschedWaitEvent(devId, grpId, threadId, timeout, event);
    if (ret == DRV_ERROR_NO_EVENT || ret == DRV_ERROR_WAIT_TIMEOUT) {
        return HCCL_E_AGAIN;
    }
    CHK_PRT_RET(ret != DRV_ERROR_NONE, HCCL_ERROR("[hrtHalEschedWaitEvent]errNo[0x%016llx] hrtHalEschedWaitEvent fail,"
        "return[%d], para: devId[%u].", HCCL_ERROR_CODE(HCCL_E_DRV), ret, devId), HCCL_E_DRV);
    return HCCL_SUCCESS;
}

HcclResult hrtHalEschedRegisterAckFunc(unsigned int eventId,
    void (*ackFunc)(unsigned int devId, unsigned int subeventId, u8 *msg, unsigned int msgLen))
{
    CHK_PTR_NULL(ackFunc);
    drvError_t ret = DlHalFunction::GetInstance().dlHalEschedRegisterAckFunc(HCCL_ESCHED_GROUP_ID, eventId, ackFunc);
    CHK_PRT_RET(ret != DRV_ERROR_NONE, HCCL_ERROR("errNo[0x%016llx] hrtHalEschedRegisterAckFunc fail,"
        "return[%d], para: eventId[%u].", HCCL_ERROR_CODE(HCCL_E_DRV), ret, eventId), HCCL_E_DRV);
    return HCCL_SUCCESS;
}

HcclResult hrtHalEschedRegisterAckFuncWithGrpid(unsigned int grpid, unsigned int eventId,
    void (*ackFunc)(unsigned int devId, unsigned int subeventId, u8 *msg, unsigned int msgLen))
{
    CHK_PTR_NULL(ackFunc);
    drvError_t ret = DlHalFunction::GetInstance().dlHalEschedRegisterAckFunc(grpid, eventId, ackFunc);
    CHK_PRT_RET(ret != DRV_ERROR_NONE, HCCL_ERROR("errNo[0x%016llx] hrtHalEschedRegisterAckFunc fail,"
        "return[%d], para: eventId[%u].", HCCL_ERROR_CODE(HCCL_E_DRV), ret, eventId), HCCL_E_DRV);
    return HCCL_SUCCESS;
}

HcclResult hrtHalDrvOpenIpcNotify(const char *name, struct drvIpcNotifyInfo *notify)
{
    CHK_PTR_NULL(name);
    CHK_PTR_NULL(notify);
    drvError_t ret = DlHalFunction::GetInstance().dlHalDrvOpenIpcNotify(name, notify);
    CHK_PRT_RET(ret != DRV_ERROR_NONE, HCCL_ERROR("errNo[0x%016llx] hrtHalDrvOpenIpcNotify fail,"
        "return[%d], para: name[%s].", HCCL_ERROR_CODE(HCCL_E_DRV), ret, name), HCCL_E_DRV);
    HCCL_DEBUG("[hrtHalDrvOpenIpcNotify]name:[%s] tsId:[%u] devId:[%u] notifyId:[%u]", name,
        notify->tsId, notify->devId, notify->notifyId);
    return HCCL_SUCCESS;
}

HcclResult hrtHalDrvCloseIpcNotify(const char *name, struct drvIpcNotifyInfo *notify)
{
    CHK_PTR_NULL(name);
    CHK_PTR_NULL(notify);
    drvError_t ret = DlHalFunction::GetInstance().dlHalDrvCloseIpcNotify(name, notify);
    CHK_PRT_RET(ret != DRV_ERROR_NONE, HCCL_ERROR("errNo[0x%016llx] hrtHalDrvCloseIpcNotify fail,"
        "return[%d], para: name[%s].", HCCL_ERROR_CODE(HCCL_E_DRV), ret, name), HCCL_E_DRV);
    HCCL_DEBUG("[hrtHalDrvCloseIpcNotify]name:[%s] tsId:[%u] devId:[%u] notifyId:[%u]", name,
        notify->tsId, notify->devId, notify->notifyId);
    return HCCL_SUCCESS;
}

HcclResult hrtHalDrvIpcNotifyRecord(const char *name)
{
    CHK_PTR_NULL(name);
    HCCL_INFO("Entry-hrtHalDrvIpcNotifyRecord");
    drvError_t ret = DlHalFunction::GetInstance().dlHalDrvIpcNotifyRecord(name);
    CHK_PRT_RET(ret != DRV_ERROR_NONE, HCCL_ERROR("errNo[0x%016llx] hrtHalDrvIpcNotifyRecord fail,"
        "return[%d], para: name[%s].", HCCL_ERROR_CODE(HCCL_E_DRV), ret, name), HCCL_E_DRV);
    HCCL_DEBUG("[hrtHalDrvIpcNotifyRecord] name:[%s]", name);
    return HCCL_SUCCESS;
}

HcclResult HrtHalDrvQueryProcessHostPid(int pid, unsigned int *chipId, unsigned int *vfid,
    unsigned int *hostPid, unsigned int *cpType)
{
    CHK_PTR_NULL(chipId);
    CHK_PTR_NULL(vfid);
    CHK_PTR_NULL(hostPid);
    CHK_PTR_NULL(cpType);
    drvError_t ret = DlHalFunction::GetInstance().dlHalDrvQueryProcessHostPid(pid,
        chipId, vfid, hostPid, cpType);
    CHK_PRT_RET(ret != DRV_ERROR_NONE, HCCL_ERROR("errNo[0x%016llx] HrtHalDrvQueryProcessHostPid fail,"
        "return[%d], para: pid[%d].", HCCL_ERROR_CODE(HCCL_E_DRV), ret, pid), HCCL_E_DRV);
    HCCL_INFO("HrtHalDrvQueryProcessHostPid pid[%d] hostPid[%u]", pid, *hostPid);
    return HCCL_SUCCESS;
}

HcclResult hrtDrvMemCpy(void *dst, uint64_t destMax, const void *src, uint64_t count)
{
    // 参数有效性检查
    CHK_PTR_NULL(dst);
    CHK_PTR_NULL(src);

    uint64_t dstAddr = reinterpret_cast<uintptr_t>(dst);
    uint64_t srcAddr = reinterpret_cast<uintptr_t>(const_cast<void *>(src));
    drvError_t ret = DlHalFunction::GetInstance().dlDrvMemCpy(dstAddr, destMax, srcAddr, count);
    CHK_PRT_RET(ret != DRV_ERROR_NONE, HCCL_ERROR("errNo[0x%016llx] hrtDrvMemCpy fail,"
        "return[%d].", HCCL_ERROR_CODE(HCCL_E_DRV), ret), HCCL_E_DRV);
    return HCCL_SUCCESS;
}

HcclResult hrtDrvGetDevNum(uint32_t *num_dev)
{
    // 参数有效性检查
    CHK_PTR_NULL(num_dev);
    drvError_t ret = DlHalFunction::GetInstance().dlHalDrvGetDevNum(num_dev);
    if (ret == DRV_ERROR_NOT_SUPPORT) {
        // 通用服务器不支持该接口，默认num_dev为0，返回成功
        *num_dev = 0;
        return HCCL_SUCCESS;
    }
    CHK_PRT_RET(ret != DRV_ERROR_NONE, HCCL_ERROR("errNo[0x%016llx] hrtDrvGetDevNum fail,"
        "return[%d].", HCCL_ERROR_CODE(HCCL_E_DRV), ret), HCCL_E_DRV);
    return HCCL_SUCCESS;
}

HcclResult hrtHalGetDeviceInfo(uint32_t devId, int32_t moduleType, int32_t infoType, int64_t *value)
{
    // 参数有效性检查
    CHK_PTR_NULL(value);
    HCCL_INFO("Entry-hrtHalGetDeviceInfo");
    drvError_t ret = DlHalFunction::GetInstance().dlHalGetDeviceInfo(devId, moduleType, infoType, value);
    CHK_PRT_RET(ret == DRV_ERROR_NOT_SUPPORT, HCCL_WARNING("hrtHalGetDeviceInfo not support"
        "return[%d].", HCCL_ERROR_CODE(DRV_ERROR_NOT_SUPPORT), ret), HCCL_E_NOT_SUPPORT);
    CHK_PRT_RET(ret != DRV_ERROR_NONE, HCCL_ERROR("errNo[0x%016llx] hrtHalGetDeviceInfo fail,"
        "return[%d].", HCCL_ERROR_CODE(HCCL_E_DRV), ret), HCCL_E_DRV);
    return HCCL_SUCCESS;
}

void hrtDrvDeviceGetBareTgid(s32 &pid)
{
    pid = DlHalFunction::GetInstance().dlDrvDeviceGetBareTgid();

    return ;
}

HcclResult hrtHalGrpQuery(GroupQueryCmdType cmd, void *inBuff, unsigned int inLen, void *outBuff,
    unsigned int *outLen)
{
    CHK_PTR_NULL(inBuff);
    CHK_PTR_NULL(outBuff);
    CHK_PTR_NULL(outLen);
    drvError_t ret = DlHalFunction::GetInstance().dlHalGrpQuery(cmd, inBuff, inLen, outBuff, outLen);
    CHK_PRT_RET(ret == DRV_ERROR_NOT_SUPPORT, HCCL_WARNING("dlHalGrpQuery is not support."), HCCL_SUCCESS);
    CHK_PRT_RET(ret != DRV_ERROR_NONE, HCCL_ERROR("errNo[0x%016llx] hrtHalGrpQuery fail,"
        "return[%d], para: cmd[%d].", HCCL_ERROR_CODE(HCCL_E_DRV), ret, cmd), HCCL_E_DRV);
    return HCCL_SUCCESS;
}

HcclResult hrtEschedQueryInfo(unsigned int devId, ESCHED_QUERY_TYPE type, struct esched_input_info *inPut,
    struct esched_output_info *outPut)
{
    drvError_t ret = DlHalFunction::GetInstance().dlEschedQueryInfo(devId, type, inPut, outPut);
    CHK_PRT_RET(ret != DRV_ERROR_NONE, HCCL_WARNING("errNo[0x%016llx] hrtEschedQueryInfo null,"
        "return[%d], para: type[%d].", HCCL_ERROR_CODE(HCCL_E_DRV), ret, type), HCCL_E_DRV);
    return HCCL_SUCCESS;
}

HcclResult hrtDrvGetPlatformInfo(uint32_t *info)
{
    // 参数有效性检查
    CHK_PTR_NULL(info);
    HCCL_INFO("Entry-hrtDrvGetPlatformInfo");
    drvError_t ret = DlHalFunction::GetInstance().dlHalDrvGetPlatformInfo(info);
    CHK_PRT_RET(ret != DRV_ERROR_NONE, HCCL_ERROR("errNo[0x%016llx] hrtDrvGetPlatformInfo fail,"
        "return[%d].", HCCL_ERROR_CODE(HCCL_E_DRV), ret), HCCL_E_DRV);
    return HCCL_SUCCESS;
}

HcclResult hrtHalGetChipInfo(uint32_t devId, std::string &chipName)
{
    // 参数有效性检查
    CHK_SMART_PTR_NULL(DlHalFunction::GetInstance().dlHalGetChipInfo);
    halChipInfo chipInfo = {0};
    drvError_t ret = DlHalFunction::GetInstance().dlHalGetChipInfo(devId, &chipInfo);
    CHK_PRT_RET(ret != DRV_ERROR_NONE, HCCL_ERROR("errNo[0x%016llx] hrtHalGetChipInfo fail,"
        "return[%d].", HCCL_ERROR_CODE(HCCL_E_DRV), ret), HCCL_E_DRV);
    chipName = reinterpret_cast<char *>(chipInfo.name);
    HCCL_INFO("hrtHalGetChipInfo succ chipName[%s]", chipName.c_str());
    return HCCL_SUCCESS;
}

HcclResult hrtHalBindCgroup(BIND_CGROUP_TYPE bindType)
{
    if (DlHalFunction::GetInstance().dlHalBindCgroup == nullptr) {
        HCCL_ERROR("dlHalBindCgroup is nullptr, can not use dlHalBindCgroup");
        return HCCL_E_DRV;
    }
    drvError_t ret = DlHalFunction::GetInstance().dlHalBindCgroup(bindType);
    CHK_PRT_RET(ret != DRV_ERROR_NONE, HCCL_ERROR("errNo[0x%016llx] hrtHalBindCgroup fail,"
        "return[%d].", HCCL_ERROR_CODE(HCCL_E_DRV), ret), HCCL_E_DRV);
    return HCCL_SUCCESS;
}

HcclResult hrtDrvDeviceGetPhyIdByIndex(u32 deviceLogicId, u32 &devicePhyId)
{
    if (DlHalFunction::GetInstance().dlDrvDeviceGetPhyIdByIndex == nullptr) {
        HCCL_ERROR("dlDrvDeviceGetPhyIdByIndex is nullptr, can not use dlDrvDeviceGetPhyIdByIndex");
        return HCCL_E_DRV;
    }

    drvError_t ret = DlHalFunction::GetInstance().dlDrvDeviceGetPhyIdByIndex(deviceLogicId, &devicePhyId);
    CHK_PRT_RET(ret != DRV_ERROR_NONE, HCCL_ERROR("[hrtDrvDeviceGetPhyIdByIndex]errNo[0x%016llx]"
        "hrtDrvDeviceGetPhyIdByIndex fail, return[%d], para: deviceLogicId[%u].",
        HCCL_ERROR_CODE(HCCL_E_DRV), ret, deviceLogicId), HCCL_E_DRV);

    return HCCL_SUCCESS;
}

void MemoryPreFetchImpl(u64 start, u64 end, u32 pageSize)
{
    // 多线程并发对待映射的内存进行逐页表的预访问
    volatile uint64_t* ptr;
    for (u64 i = start; i < end; i += pageSize) {
        ptr = reinterpret_cast<volatile uint64_t*>(i);
        *ptr;
    }
}

HcclResult MemoryPreFetch(u64 size, void *hostPtr)
{
    if (size >= PRE_FETCH_MEMORY_THRESHOLD) {
        std::vector<std::unique_ptr<std::thread>> threads(PRE_FETCH_THREADS_NUM);
        u64 chunkSize = size / PRE_FETCH_THREADS_NUM;
        u64 hostPtrUpperLimit = size + reinterpret_cast<uintptr_t>(hostPtr);
        for (unsigned int i = 0; i < PRE_FETCH_THREADS_NUM; ++i) {
            u64 start = i * chunkSize + reinterpret_cast<uintptr_t>(hostPtr);
            u64 end = (start + chunkSize < hostPtrUpperLimit) ?
                start + chunkSize : hostPtrUpperLimit;
            threads[i].reset(new (std::nothrow) std::thread(&MemoryPreFetchImpl, start, end,
                MEMORY_PAGE_SIZE));
            CHK_PRT_RET(!threads[i], HCCL_ERROR("[MemoryPreFetch]threads[%d] threads reset failed.",
                i), HCCL_E_INTERNAL);
        }

        for (auto& thread : threads) {
            thread->join();
        }
    }
    return HCCL_SUCCESS;
}

HcclResult hrtHalHostRegister(void *hostPtr, u64 size, u32 flag, u32 devid, void *&devPtr)
{
    CHK_PTR_NULL(hostPtr);
    if (flag == HOST_MEM_MAP_DEV_PCIE_TH || flag == HOST_MEM_MAP_DEV) {
        CHK_RET(MemoryPreFetch(size, hostPtr));
    }

    if (DlHalFunction::GetInstance().dlHalHostRegister == nullptr) {
        HCCL_ERROR("dlHalHostRegister is nullptr, can not use dlHalHostRegister");
        return HCCL_E_DRV;
    }

    drvError_t ret = DlHalFunction::GetInstance().dlHalHostRegister(hostPtr, size, flag, devid, &devPtr);
    CHK_PRT_RET(ret != DRV_ERROR_NONE, HCCL_ERROR("[hrtHalHostRegister]errNo[0x%016llx]"
        "hrtHalHostRegister fail, return[%d], para: size[%llu] flag[%u] devid[%u].",
        HCCL_ERROR_CODE(HCCL_E_DRV), ret, size, flag, devid), HCCL_E_DRV);
    return HCCL_SUCCESS;
}

HcclResult hrtHalHostUnregister(void *hostPtr, u32 devid)
{
    CHK_PTR_NULL(hostPtr);
    if (DlHalFunction::GetInstance().dlHalHostUnregister == nullptr) {
        HCCL_ERROR("dlHalHostUnregister is nullptr, can not use dlHalHostUnregister");
        return HCCL_E_DRV;
    }

    drvError_t ret = DlHalFunction::GetInstance().dlHalHostUnregister(hostPtr, devid);
    CHK_PRT_RET(ret != DRV_ERROR_NONE, HCCL_ERROR("[hrtHalHostUnregister]errNo[0x%016llx]"
        "hrtHalHostUnregister fail, return[%d], para: devid[%u].",
        HCCL_ERROR_CODE(HCCL_E_DRV), ret, devid), HCCL_E_DRV);

    return HCCL_SUCCESS;
}

HcclResult hrtHalHostUnregisterEx(void *hostPtr, u32 devid, u32 flag)
{
    CHK_PTR_NULL(hostPtr);
    if (DlHalFunction::GetInstance().dlHalHostUnregisterEx == nullptr) {
        HCCL_ERROR("dlHalHostUnregisterEx is nullptr, can not use dlHalHostUnregisterEx");
        return HCCL_E_DRV;
    }

    drvError_t ret = DlHalFunction::GetInstance().dlHalHostUnregisterEx(hostPtr, devid, flag);
    CHK_PRT_RET(ret != DRV_ERROR_NONE, HCCL_ERROR("[hrtHalHostUnregisterEx]errNo[0x%016llx]"
        "hrtHalHostUnregisterEx fail, return[%d], para: devid[%u].",
        HCCL_ERROR_CODE(HCCL_E_DRV), ret, devid), HCCL_E_DRV);

    return HCCL_SUCCESS;
}

HcclResult hrtHalMemCtl(int type, void *input, size_t inputSize, void *output, size_t *outputSize)
{
    CHK_PTR_NULL(input);
    CHK_PTR_NULL(output);
    CHK_PTR_NULL(outputSize);
    if (DlHalFunction::GetInstance().dlHalMemCtl == nullptr) {
        HCCL_ERROR("dlHalMemCtl is nullptr, can not use dlHalMemCtl");
        return HCCL_E_DRV;
    }

    drvError_t ret = DlHalFunction::GetInstance().dlHalMemCtl(type, input, inputSize, output, outputSize);
    CHK_PRT_RET(ret != DRV_ERROR_NONE, HCCL_ERROR("[dlHalMemCtl]errNo[0x%016llx]"
        "dlHalMemCtl fail, return[%d], para: type[%u].",
        HCCL_ERROR_CODE(HCCL_E_DRV), ret, type), HCCL_E_DRV);

    return HCCL_SUCCESS;
}

HcclResult hrtHalSensorNodeRegister(uint32_t devId, struct halSensorNodeCfg *cfg, uint64_t *handle)
{
#ifdef CCL_KERNEL
    CHK_PTR_NULL(cfg);
    CHK_PTR_NULL(handle);
    if (DlHalFunction::GetInstance().dlHalSensorNodeRegister == nullptr) {
        HCCL_ERROR("dlHalSensorNodeRegister is nullptr, can not use dlHalSensorNodeRegister");
        return HCCL_E_DRV;
    }

    drvError_t ret = DlHalFunction::GetInstance().dlHalSensorNodeRegister(devId, cfg, handle);
    CHK_PRT_RET(ret != DRV_ERROR_NONE, HCCL_ERROR("[hrtHalSensorNodeRegister]errNo[0x%016llx]"
        "hrtHalSensorNodeRegister fail, return[%d], para: devid[%u], nodeName[%s], nodeType[%u], sensorType[%u].",
        HCCL_ERROR_CODE(HCCL_E_DRV), ret, devId, cfg->name, cfg->NodeType, cfg->SensorType), HCCL_E_DRV);

    return HCCL_SUCCESS;
#else
    HCCL_ERROR("[halSensorNodeRegister]Does not support this interface.");
    return HCCL_E_NOT_SUPPORT;
#endif
}

HcclResult hrtHalSensorNodeUnregister(uint32_t devId, uint64_t handle)
{
#ifdef CCL_KERNEL
    if (DlHalFunction::GetInstance().dlHalSensorNodeUnregister == nullptr) {
        HCCL_ERROR("dlHalSensorNodeUnregister is nullptr, can not use dlHalSensorNodeUnregister");
        return HCCL_E_DRV;
    }

    drvError_t ret = DlHalFunction::GetInstance().dlHalSensorNodeUnregister(devId, handle);
    CHK_PRT_RET(ret != DRV_ERROR_NONE, HCCL_ERROR("[hrtHalSensorNodeUnregister]errNo[0x%016llx]"
        "hrtHalSensorNodeUnregister fail, return[%d], para: devid[%u], handle[%llu].",
        HCCL_ERROR_CODE(HCCL_E_DRV), ret, devId, handle), HCCL_E_DRV);

    return HCCL_SUCCESS;
#else
    HCCL_ERROR("[halSensorNodeUnregister]Does not support this interface.");
    return HCCL_E_NOT_SUPPORT;
#endif
}

HcclResult hrtHalSensorNodeUpdateState(uint32_t devId, uint64_t handle, int val, halGeneralEventType_t assertion)
{
#ifdef CCL_KERNEL
    if (DlHalFunction::GetInstance().dlHalSensorNodeUpdateState == nullptr) {
        HCCL_ERROR("dlHalSensorNodeUpdateState is nullptr, can not use dlHalSensorNodeUpdateState");
        return HCCL_E_DRV;
    }

    drvError_t ret = DlHalFunction::GetInstance().dlHalSensorNodeUpdateState(devId, handle, val, assertion);
    CHK_PRT_RET(ret != DRV_ERROR_NONE, HCCL_RUN_WARNING("[hrtHalSensorNodeUpdateState]errNo[0x%016llx]"
        "hrtHalSensorNodeUpdateState fail, return[%d], para: devid[%u], handle[%llu], val[%d], assertion[%u].",
        HCCL_ERROR_CODE(HCCL_E_DRV), ret, devId, handle, val, assertion), HCCL_E_DRV);

    return HCCL_SUCCESS;
#else
    HCCL_ERROR("[halSensorNodeUpdateState]Does not support this interface.");
    return HCCL_E_NOT_SUPPORT;
#endif
}


HcclResult hrtHalGetDeviceType(const uint32_t devId, DevType &devType)
{
    devType = DevType::DEV_TYPE_COUNT;
    int64_t hardwareVersion;
    HcclResult ret = hrtHalGetDeviceInfo(devId, MODULE_TYPE_SYSTEM, INFO_TYPE_VERSION, &hardwareVersion);
    if (ret == HCCL_E_NOT_SUPPORT) {
        devType = DevType::DEV_TYPE_NOSOC;
        return HCCL_SUCCESS;
    } else if (ret != HCCL_SUCCESS) {
        HCCL_ERROR("[hrtHalGetDeviceType]Get device info failed, ret[%d]", ret);
        return ret;
    }
    std::string chipName;
    ret= hrtHalGetChipInfo(devId, chipName);
    if (ret != HCCL_SUCCESS) {
        HCCL_ERROR("hrtHalGetChipInfo failed, ret[%d], devId[%u]", ret, devId);
        return ret;
    }

    const rtChipType_t chipType = static_cast<rtChipType_t>(PLAT_GET_CHIP(hardwareVersion));
    HCCL_INFO("[Get][DeviceType]ChipType %u hardwareVersion %lld, name[%s].",
        chipType, hardwareVersion, chipName.c_str());

    switch (chipType) {
        case CHIP_DC:   // 310P1/P3
            {
                const std::unordered_map<std::string, DevType> SOC_NAME_CONVERT{
                    {"310P1", DevType::DEV_TYPE_310P1},
                    {"310P3", DevType::DEV_TYPE_310P3},
                    {"310P5", DevType::DEV_TYPE_310P3},
                    {"310P7", DevType::DEV_TYPE_310P3}};
                auto iter = SOC_NAME_CONVERT.find(chipName);
                if (iter == SOC_NAME_CONVERT.end()) {
                    HCCL_ERROR("[Get][DeviceType]errNo[0x%016llx] hrtHalGetChipInfo get illegal chipver, "
                    "chip_name[%s].", HCCL_ERROR_CODE(HCCL_E_DRV), chipName.c_str());
                    return HCCL_E_DRV;
                }
                devType = iter->second;
                break;
            }
        case CHIP_CLOUD:    // 910A1
            {
                HCCL_INFO("[Get][DeviceType]get 910A %lld.", hardwareVersion);
                devType = DevType::DEV_TYPE_910;
                break;
            }
        case CHIP_CLOUD_V2: // 910A2/910A3
            {
                constexpr u64 DEVDRV_PLATFORM_CLOUD_V3 = PLAT_COMBINE(ARCH_V100, CHIP_CLOUD_V2, VER_NA);
                if (hardwareVersion == DEVDRV_PLATFORM_CLOUD_V3) {  // 910A3
                    const std::string CHIP_NAME_910_93 = "910_93";
                    if (chipName.find(CHIP_NAME_910_93) != std::string::npos) {
                        HCCL_INFO("[Get][DeviceType]get 910_93 %lld", hardwareVersion);
                        devType = DevType::DEV_TYPE_910_93;
                        break;
                    }
                    HCCL_INFO("[Get][DeviceType]get hardwareVersion %lld", hardwareVersion);
                }
                HCCL_INFO("[Get][DeviceType]get 910B %lld.", hardwareVersion);
                devType = DevType::DEV_TYPE_910B;
                break;
            }
        default:
            {
                // 其他芯片不支持
                HCCL_ERROR("Hardware version %lld is unsupported", hardwareVersion);
                return HCCL_E_DRV;
            }
    }
    HCCL_INFO("[Get][DeviceType]deviceId[%u] get devType[%d] success!", devId, devType);
    return HCCL_SUCCESS;
}